#include "stdafx.h"
#include "ActionTable.h"


namespace compile
{
	// ------------------------------- public -----------------------------------
	ActionTable::ActionTable()
	{
	}

	ActionTable::ActionTable(vector<Word> word_vector)
		:ActionTable()
	{
		initIndex(word_vector);
	}


	ActionTable::~ActionTable()
	{
		index_set.clear();
		action_table.clear();
	}

	/**
	* initiate set about index sign
	* @param {vector<Word>} word_vector
	*/
	void ActionTable::initIndex(vector<Word> word_vector)
	{
		for (UNI i = 0; i < word_vector.size(); ++i)
		{
			string content = word_vector.at(i).getContent();

			for (UNI j = 0; j < content.length(); ++j)
			{

				// 标记终结符
				if (ifEndSign(content[j]))
				{
					index_set.insert(polyfillChar(content[j]));
				}
			}
		}

		// 终止符加入集合
		index_set.insert("$");
	}


	/**
	* search index
	* @param {pair<string, string>} table row(status number) 
	*								and column(end sign)
	* @return word content or empty string
	*/

	string ActionTable::searchTable(pair<string, string> index) const
	{
		auto it = action_table.find(index);
		if (it == action_table.end())
		{
			return "";
		}

		return it->second;
	}


	/**
	* print table
	*/

	void ActionTable::printTable() const
	{
		cout << endl << "Action Table:" << endl;
		for (auto it = action_table.begin(); it != action_table.end(); ++it)
		{
			cout << std::get<0>(it->first) << ", " << std::get<1>(it->first)
				<< ":\t" << it->second << endl;
		}
		cout << endl;
	}

	/**
	* 获取action table
	*/
	map<pair<string, string>, string> ActionTable::getTable() const
	{
		return action_table;
	}

	/**
	* 设置Action Table里的数据
	* @param {pair<string, string>} index - 插入的索引
	* @param {string} content - 插入的内容
	*/
	void ActionTable::setTable(pair<string, string> index, string content)
	{
		auto it = action_table.find(index);

		if (it != action_table.end())
		{
			errorAndExit();
		}

		action_table.insert(map<pair<string, string>, string>
			::value_type(index, content));
	}


	set<string> ActionTable::getIndexSet() const
	{
		return index_set;
	}
	// ---------------------------------- End public --------------------------------

}